package sustav.dekoderi;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.ListIterator;

import javax.swing.text.html.HTMLDocument.Iterator;

public class EntropijskiDekoder {
	
	private HashMap<Integer,String> rjecnik;
	private String binarniUlaz;
	private LinkedList<Integer> ulazniNiz;
	private LinkedList<String> dekodiraniNiz;
	private char[] simboli;
	/**
	 *Klasa EntropijskiDekoder sluzi za entropijsku dekompresiju
	 *metodom LZW. Konstruktor klase prima polje simbola koji
	 *su osnovni simboli (abeceda) na osnovu kojih se gradi inicijalni rijecnik. 
	 */
	public EntropijskiDekoder (char[] simboli, String binarniNiz){
		this.binarniUlaz = binarniNiz;//String.valueOf(binarniNiz);
		this.simboli = simboli;	
		initRjecnik();
	}
	
	
	public void initRjecnik(){ 
		
		this.rjecnik=new HashMap<Integer,String>();
		
		for(int i = 0; i< this.simboli.length; i++){
			String s = Character.toString(simboli[i]);
			rjecnik.put(i+1,s );
		}
	}
	
	public void listaIzBinarnog ( String binarniNiz ){
		this.ulazniNiz = new LinkedList<Integer>();
		int j = 0;
		int k = 9;
		String element;
		
		while (j<=binarniNiz.length() && k<=binarniNiz.length()){
			element = binarniNiz.substring(j, k);
			int broj = Integer.parseInt(element, 2);
			this.ulazniNiz.add(broj);
			j = j + 9;
			k = k + 9;
		}
	}
	public void dekodiraj(){
		int prvi, sljedeci,m,n;
		int velicina = this.rjecnik.size()+1;
		String stariKod, noviKod="",rijec, znak="", niz;
		
		this.dekodiraniNiz = new LinkedList<String>();
		ListIterator<Integer> itr = ulazniNiz.listIterator();
		
		prvi = itr.next();
		stariKod = this.rjecnik.get(prvi);
		this.dekodiraniNiz.add(stariKod);
		znak = stariKod;
		
		while(itr.hasNext()){
			sljedeci = itr.next();
			
			if(!this.rjecnik.containsKey(sljedeci)){
				niz = stariKod;
				niz = niz + znak;
				noviKod = niz;
			}
			else{
				noviKod = this.rjecnik.get(sljedeci);
				niz = noviKod;
				}
			n=1;
			for(m=0; m<niz.length(); m++){
				this.dekodiraniNiz.add(niz.substring(m, n));
				n++;
			}	
			znak = niz.substring(0, 1);
			rijec= stariKod + znak;
			this.rjecnik.put(velicina++, rijec);
			
			stariKod = noviKod;
		}
		System.out.println("");
	}
	


	
 	
	public LinkedList<Integer> getUlazniNiz(){
		return this.ulazniNiz;
	}
	public HashMap<Integer,String> getRjecnik(){
		return this.rjecnik;
	}
	
	public char[] getDekodiraniNiz(){	
		
		//Prebaci String listu u Character listu
		ListIterator<String> itr=(ListIterator<String>) this.dekodiraniNiz.iterator();
		
		char[] tmpNiz=new char[this.dekodiraniNiz.size()];
		int j=0;
		while(itr.hasNext()){
			String s=itr.next();
			tmpNiz[j]=s.toCharArray()[0];
			j++;
		}
		
		
		return tmpNiz;
	}
}
